# -*- coding: UTF-8 -*-

from datetime import datetime
import sys
from sqlalchemy import and_,  func, or_
from typing import Dict, List, Any, Generator

from sqlalchemy import Boolean, Column, DateTime, Integer, String, Index, Table, ForeignKey, text, JSON, TEXT, distinct
from sqlalchemy.orm import Session, relationship
from common.database import Base
from common.database import SessionMixin
from common.utils import is_empty
from core.logger import logger



__all__ = ['NCN9eAlarmRecord']

class NCN9eAlarmRecord(Base, SessionMixin):
    '''
    n9e告警记录表
    '''
    __tablename__ = "nc_n9e_alarm_record"
    name = Column(String(256), nullable=False, comment='告警记录名称')
    cluster = Column(String(32), nullable=False, index=True, comment='集群名称')
    classify = Column(String(32), nullable=False, index=True, comment='告警归类')
    # firing / resolved
    status = Column(String(16), nullable=False, index=True, comment='告警状态')
    target = Column(String(128), nullable=False, index=True, comment='监控目标')
    number = Column(Integer, nullable=False, comment='告警次数')
    fingerprint = Column(String(64), nullable=False, index=True, comment='告警指纹')
    # critical:严重(电话部门负责人), major:重要警告(电话告警处理人), warning:一般告警(短信告警处理人),
    # info:提示告警(企业微信告警处理人), nothing:(不告警)
    level = Column(String(16), nullable=True, default="info", index=True, comment='告警级别')
    notify_users = Column(JSON, nullable=False, default=[], comment='通知人员')
    notice_count = Column(Integer, nullable=True, comment='已通知的次数')
    # 通知的类型：alarm(告警)、subscribe(订阅)
    notice_type = Column(String(16), nullable=False, comment='通知类型')
    labels = Column(JSON, nullable=False, default={},comment='告警标签')
    annotations = Column(JSON, nullable=False, default={}, comment='规则注释')
    value = Column(String(32), default="", comment='触发值')
    maintain_begin = Column(DateTime, nullable=True, comment='维护开始时间')
    maintain_end = Column(DateTime, nullable=True, comment='维护结束时间')
    starts_at = Column(DateTime, nullable=True, comment='告警开始时间')
    ends_at = Column(DateTime, nullable=True, comment='告警结束时间')
    update_at = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment='更新时间')
    comment = Column(String(256), nullable=True, comment='告警记录说明')


    __table_args__ = (
        {
            'mysql_engine': 'innodb',
            'mysql_charset': 'utf8mb4',
            'mysql_collate': 'utf8mb4_unicode_ci',
            'extend_existing': True,
            'mysql_row_format': 'dynamic',
        }
    )

    def __repr__(self):
        return f"<manage_notice_user='{self.name}': {self.telephone} '>"


    def object_to_dict(self, db: Session):
        result = {
            key: getattr(self, key)
            for key in self.__mapper__.c.keys()
        }
        
        return result



    @classmethod
    def get_object_info_by_alert(cls, db: Session, alert_info: dict, status: str):
        """
        根据告警信息查找告警的记录
        """
        object_info = db.query(cls).filter(
            cls.cluster == alert_info["cluster"],
            cls.name == alert_info["name"],
            cls.fingerprint == alert_info["fingerprint"],
            cls.notice_type == alert_info["notice_type"],
            cls.status == status
        ).order_by(cls.update_at.desc()).to_dict_first()
        return object_info


    @classmethod
    def get_object_info_by_fingerprint(cls, db: Session, fingerprint: str, notice_type: str, status: str):
        """
        根据告警指纹查找告警的记录
        """
        object_info = db.query(cls).filter(
            cls.fingerprint == fingerprint,
            cls.notice_type == notice_type,
            cls.status == status
        ).order_by(cls.update_at.desc()).to_dict_first()
        return object_info


    @classmethod
    def get_object_info_for_watchdog(cls, db: Session):
        """
        获取WatchDog的告警记录
        """
        object_info = db.query(cls).filter(
            cls.name == "N9eWatchDog",
            cls.status == "firing"
        ).order_by(cls.update_at.desc()).to_dict()
        if not object_info:
            return {}
        return object_info[0]


    @classmethod
    def get_object_info_for_block_global(cls, db: Session):
        """
        获取屏蔽全局告警的记录
        """
        object_info = db.query(cls).filter(
            cls.name == "BlockGlobalAlarm"
        ).to_dict_first()
 
        return object_info




    @classmethod
    def get_object_info_for_time(cls, db: Session, start, end):
        """
        获取指定日期的告警记录
        """
        object_info = db.query(cls).filter(and_(
            cls.starts_at >= start,
            cls.starts_at <= end)
        ).order_by(cls.starts_at.desc()).to_dict()
        return object_info


    @classmethod
    def get_object_firing_number(cls, db: Session, alert_info: dict):
        """
        获取某一个告警规则，已经告警的数量
        """
        object_info = db.query(cls).filter(
            cls.name == alert_info['name'],
            cls.status == "firing",
            cls.level == alert_info['level'],
            cls.notice_count > 0
        ).to_dict()
        
        return len(object_info)